home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / hurd / dtable.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-04  |  7.6 KB  |  279 lines

  1. /* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <hurd.h>
  21. #include <hurd/term.h>
  22. #include <hurd/fd.h>
  23. #include <gnu-stabs.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <fcntl.h>
  27. #include <limits.h>
  28. #include <cthreads.h>        /* For `struct mutex'.  */
  29. #include "set-hooks.h"
  30. #include "hurdmalloc.h"        /* XXX */
  31.  
  32.  
  33. struct mutex _hurd_dtable_lock = MUTEX_INITIALIZER; /* XXX ld bug; must init */
  34. struct hurd_fd **_hurd_dtable;
  35. int _hurd_dtablesize;
  36.  
  37.  
  38. DEFINE_HOOK (_hurd_fd_subinit, (void));
  39.  
  40. /* Initialize the file descriptor table at startup.  */
  41.  
  42. static void
  43. init_dtable (void)
  44. {
  45.   register size_t i;
  46.  
  47.   __mutex_init (&_hurd_dtable_lock);
  48.  
  49.   /* The initial size of the descriptor table is that of the passed-in
  50.      table.  It will be expanded as necessary up to _hurd_dtable_rlimit.  */
  51.   _hurd_dtablesize = _hurd_init_dtablesize;
  52.  
  53.   /* Allocate the vector of pointers.  */
  54.   _hurd_dtable = malloc (_hurd_dtablesize * sizeof (*_hurd_dtable));
  55.   if (_hurd_dtablesize != 0 && _hurd_dtable == NULL)
  56.     __libc_fatal ("hurd: Can't allocate file descriptor table\n");
  57.  
  58.   /* Initialize the descriptor table.  */
  59.   for (i = 0; i < _hurd_init_dtablesize; ++i)
  60.     {
  61.       if (_hurd_init_dtable[i] == MACH_PORT_NULL)
  62.     /* An unused descriptor is marked by a null pointer.  */
  63.     _hurd_dtable[i] = NULL;
  64.       else
  65.     {
  66.       /* Allocate a new file descriptor structure.  */
  67.       struct hurd_fd *new = malloc (sizeof (struct hurd_fd));
  68.       if (new == NULL)
  69.         __libc_fatal ("hurd: Can't allocate initial file descriptors\n");
  70.  
  71.       /* Initialize the port cells.  */
  72.       _hurd_port_init (&new->port, MACH_PORT_NULL);
  73.       _hurd_port_init (&new->ctty, MACH_PORT_NULL);
  74.  
  75.       /* Install the port in the descriptor.
  76.          This sets up all the ctty magic.  */
  77.       _hurd_port2fd (new, _hurd_init_dtable[i], 0);
  78.  
  79.       _hurd_dtable[i] = new;
  80.     }
  81.     }
  82.  
  83.   /* Clear out the initial descriptor table.
  84.      Everything must use _hurd_dtable now.  */
  85.   __vm_deallocate (__mach_task_self (),
  86.            (vm_address_t) _hurd_init_dtable,
  87.            _hurd_init_dtablesize * sizeof (_hurd_init_dtable[0]));
  88.   _hurd_init_dtable = NULL;
  89.   _hurd_init_dtablesize = 0;
  90.  
  91.   /* Initialize the remaining empty slots in the table.  */
  92.   for (; i < _hurd_dtablesize; ++i)
  93.     _hurd_dtable[i] = NULL;
  94.  
  95.   /* Run things that want to run after the file descriptor table
  96.      is initialized.  */
  97.   RUN_HOOK (_hurd_fd_subinit, ());
  98.  
  99.   (void) &init_dtable;        /* Avoid "defined but not used" warning.  */
  100. }
  101.  
  102. text_set_element (_hurd_subinit, init_dtable);
  103.  
  104. /* XXX when the linker supports it, the following functions should all be
  105.    elsewhere and just have text_set_elements here.  */
  106.  
  107. /* Called by `getdport' to do its work.  */
  108.  
  109. static file_t
  110. get_dtable_port (int fd)
  111. {
  112.   file_t dport;
  113.   int err = HURD_DPORT_USE (fd, __mach_port_mod_refs (__mach_task_self (),
  114.                               (dport = port),
  115.                               MACH_PORT_RIGHT_SEND,
  116.                               1));
  117.   if (err)
  118.     {
  119.       errno = err;
  120.       return MACH_PORT_NULL;
  121.     }
  122.   else
  123.     return dport;
  124. }
  125.  
  126. file_t (*_hurd_getdport_fn) (int fd) = get_dtable_port;
  127.  
  128. #include <hurd/signal.h>
  129.  
  130. /* We are in the child fork; the dtable lock is still held.
  131.    The parent has inserted send rights for all the normal io ports,
  132.    but we must recover ctty-special ports for ourselves.  */
  133. static error_t
  134. fork_child_dtable (void)
  135. {
  136.   error_t err;
  137.   int i;
  138.  
  139.   err = 0;
  140.  
  141.   for (i = 0; !err && i < _hurd_dtablesize; ++i)
  142.     {
  143.       struct hurd_fd *d = _hurd_dtable[i];
  144.       if (d == NULL)
  145.     continue;
  146.  
  147.       /* No other thread is using the send rights in the child task.  */
  148.       d->port.users = d->ctty.users = NULL;
  149.  
  150.       if (d->ctty.port != MACH_PORT_NULL)
  151.     {
  152.       /* There was a ctty-special port in the parent.
  153.          We need to get one for ourselves too.  */
  154.       __mach_port_deallocate (__mach_task_self (), d->ctty.port);
  155.       err = __term_open_ctty (d->port.port, _hurd_pid, _hurd_pgrp,
  156.                   &d->ctty.port);
  157.       if (err)
  158.         d->ctty.port = MACH_PORT_NULL;
  159.     }
  160.  
  161.       /* XXX for each fd with a cntlmap, reauth and re-map_cntl.  */
  162.     }
  163.   return err;
  164.  
  165.   (void) &fork_child_dtable;    /* Avoid "defined but not used" warning.  */
  166. }
  167.  
  168. data_set_element (_hurd_fork_locks, _hurd_dtable_lock);    /* XXX ld bug: bss */
  169. text_set_element (_hurd_fork_child_hook, fork_child_dtable);
  170.  
  171. /* Called when our process group has changed.  */
  172.  
  173. static void
  174. ctty_new_pgrp (void)
  175. {
  176.   int i;
  177.   
  178.   HURD_CRITICAL_BEGIN;
  179.   __mutex_lock (&_hurd_dtable_lock);
  180.  
  181.   for (i = 0; i < _hurd_dtablesize; ++i)
  182.     {
  183.       struct hurd_fd *const d = _hurd_dtable[i];
  184.       struct hurd_userlink ulink, ctty_ulink;
  185.       io_t port, ctty;
  186.  
  187.       if (d == NULL)
  188.     /* Nothing to do for an unused descriptor cell.  */
  189.     continue;
  190.  
  191.       port = _hurd_port_get (&d->port, &ulink);
  192.       ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
  193.  
  194.       if (ctty != MACH_PORT_NULL)
  195.     {
  196.       /* This fd has a ctty-special port.  We need a new one, to tell
  197.              the io server of our different process group.  */
  198.       io_t new;
  199.       if (__term_open_ctty (port, _hurd_pid, _hurd_pgrp, &new))
  200.         new = MACH_PORT_NULL;
  201.       _hurd_port_set (&d->ctty, new);
  202.     }
  203.  
  204.       _hurd_port_free (&d->port, &ulink, port);
  205.       _hurd_port_free (&d->ctty, &ctty_ulink, ctty);
  206.     }
  207.  
  208.   __mutex_unlock (&_hurd_dtable_lock);
  209.   HURD_CRITICAL_END;
  210.  
  211.   (void) &ctty_new_pgrp;    /* Avoid "defined but not used" warning.  */
  212. }
  213.  
  214. text_set_element (_hurd_pgrp_changed_hook, ctty_new_pgrp);
  215.  
  216. /* Called to reauthenticate the dtable when the auth port changes.  */
  217.  
  218. static void
  219. reauth_dtable (void)
  220. {
  221.   int i;
  222.  
  223.   HURD_CRITICAL_BEGIN;
  224.   __mutex_lock (&_hurd_dtable_lock);
  225.  
  226.   for (i = 0; i < _hurd_dtablesize; ++i)
  227.     {
  228.       struct hurd_fd *const d = _hurd_dtable[i];
  229.       mach_port_t new, newctty, ref;
  230.       
  231.       if (d == NULL)
  232.     /* Nothing to do for an unused descriptor cell.  */
  233.     continue;
  234.  
  235.       ref = __mach_reply_port ();
  236.  
  237.       /* Take the descriptor cell's lock.  */
  238.       __spin_lock (&d->port.lock);
  239.       
  240.       /* Reauthenticate the descriptor's port.  */
  241.       if (d->port.port != MACH_PORT_NULL &&
  242.       ! __io_reauthenticate (d->port.port,
  243.                  ref, MACH_MSG_TYPE_MAKE_SEND) &&
  244.       ! __USEPORT (AUTH, __auth_user_authenticate
  245.                (port,
  246.             d->port.port,
  247.             ref, MACH_MSG_TYPE_MAKE_SEND,
  248.             &new)))
  249.     {
  250.       /* Replace the port in the descriptor cell
  251.          with the newly reauthenticated port.  */
  252.  
  253.       if (d->ctty.port != MACH_PORT_NULL &&
  254.           ! __io_reauthenticate (d->ctty.port,
  255.                      ref, MACH_MSG_TYPE_MAKE_SEND) &&
  256.           ! __USEPORT (AUTH, __auth_user_authenticate
  257.                (port,
  258.                 d->ctty.port,
  259.                 ref, MACH_MSG_TYPE_MAKE_SEND,
  260.                 &newctty)))
  261.         _hurd_port_set (&d->ctty, newctty);
  262.  
  263.       _hurd_port_locked_set (&d->port, new);
  264.     }
  265.       else
  266.     /* Lost.  Leave this descriptor cell alone.  */
  267.     __spin_unlock (&d->port.lock);
  268.  
  269.       __mach_port_destroy (__mach_task_self (), ref);
  270.     }
  271.  
  272.   __mutex_unlock (&_hurd_dtable_lock);
  273.   HURD_CRITICAL_END;
  274.  
  275.   (void) &reauth_dtable;    /* Avoid "defined but not used" warning.  */
  276. }
  277.  
  278. text_set_element (_hurd_reauth_hook, reauth_dtable);
  279.